package com.rrd.hive.udf;

import java.io.UnsupportedEncodingException;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public class ByteCheckStringUDF extends UDF {
    public Text evaluate(String s, int length, String type, String mo)
            throws UnsupportedEncodingException {
        return ByteCheckStringUDF.evaluate(s, length, type, mo, "");
    }

    public static Text evaluate(String s, int length, String type, String mo,
            String v) throws UnsupportedEncodingException {
        Text text = new Text();
        StringBuilder sb = new StringBuilder(length);
        if (s == null || s.trim().equals("")) {
            s = v;
            text.set(s);
            return text;
        }
        //检查是否字符合规
        if (type.equals("ANC")) {
            for (char c : s.toCharArray()) {
                if (ByteCheckStringUDF.isANC(c)) {
                    sb.append(c);
                }
            }
        } else if (type.equals("AN")) {
            for (char c : s.toCharArray()) {
                if (ByteCheckStringUDF.isAN(c)) {
                    sb.append(c);
                }
            }
        } else if (type.equals("N")) {
            for (char c : s.toCharArray()) {
                if (ByteCheckStringUDF.isN(c)) {
                    sb.append(c);
                }
            }
        }
        s = sb.toString();
        if (s.trim().equals("") && mo.equals("M")) {
            s = v;
        }
        byte[] srcBytes = s.getBytes("GB18030");
        if (srcBytes.length > length) {
            s = ByteCheckStringUDF.subByteArr(s, length);
        }
        text.set(s);
        return text;

    }

    private static boolean isValid(char c) {

        String s = "<>";
        if (s.indexOf(c) >= 0) {
            return false;
        }
        return true;
    }

    private static String subByteArr(String s, int n)
            throws UnsupportedEncodingException {
        int i = s.length();
        while (s.substring(0, i).getBytes("GB18030").length > n) {
            i--;
        }
        return s.substring(0, i);
    }

    private static final int ANC1 = Integer.parseInt("A1A1", 16); //图形符号
    private static final int ANC11 = Integer.parseInt("A9FE", 16);
    private static final int ANC5 = Integer.parseInt("A840", 16);  //图形符号
    private static final int ANC51 = Integer.parseInt("A9A0", 16);
    private static final int ANC2 = Integer.parseInt("B0A1", 16);
    private static final int ANC21 = Integer.parseInt("F7FE", 16);
    private static final int ANC3 = Integer.parseInt("8140", 16);
    private static final int ANC31 = Integer.parseInt("A0FE", 16);
    private static final int ANC4 = Integer.parseInt("AA40", 16);
    private static final int ANC41 = Integer.parseInt("FEA0", 16);
    private static final int AN = 0X20;
    private static final int AN1 = 0X7E;
    private static final int N = Integer.parseInt("30", 16);
    private static final int N1 = Integer.parseInt("39", 16);

    private static boolean isN(char c) throws UnsupportedEncodingException {
        boolean bool = false;
        int ascill = ByteCheckStringUDF.char2ASCII(c);
        if (ascill >= ByteCheckStringUDF.N && ascill <= ByteCheckStringUDF.N1
            || ByteCheckStringUDF.isValid(c)) {
            bool = true;
        }
        return bool;
    }

    private static boolean isAN(char c) throws UnsupportedEncodingException {
        boolean bool = false;
        int ascill = ByteCheckStringUDF.char2ASCII(c);
        if (ascill >= ByteCheckStringUDF.AN && ascill <= ByteCheckStringUDF.AN1
            || ByteCheckStringUDF.isValid(c)) {
            bool = true;
        }
        return bool;
    }

    private static boolean isANC(char c) throws UnsupportedEncodingException {
        boolean bool = false;

        int ascill = ByteCheckStringUDF.char2ASCII(c);
        if (ByteCheckStringUDF.isValid(c) && (ascill >= ByteCheckStringUDF.AN
            && ascill <= ByteCheckStringUDF.AN1
            || ascill >= ByteCheckStringUDF.ANC1
                && ascill <= ByteCheckStringUDF.ANC11
            || ascill >= ByteCheckStringUDF.ANC5
                && ascill <= ByteCheckStringUDF.ANC51
            || ascill >= ByteCheckStringUDF.ANC2
                && ascill <= ByteCheckStringUDF.ANC21
            || ascill >= ByteCheckStringUDF.ANC3
                && ascill <= ByteCheckStringUDF.ANC31
            || ascill >= ByteCheckStringUDF.ANC4
                && ascill <= ByteCheckStringUDF.ANC41
            || ascill == 183)) {
            bool = true;
        }
        return bool;
    }

    private static String testCheck(String s)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (ByteCheckStringUDF.isANC(c)) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    private static int char2ASCII(char c) throws UnsupportedEncodingException {
        return ByteCheckStringUDF.getGBKCode(c);
    }

    private static int getGBKCode(int unicodeCode)
            throws UnsupportedEncodingException {
        if (unicodeCode >= 19968 && unicodeCode <= 40869) {
            char c = (char) unicodeCode;
            byte[] bytes = (c + "").getBytes("GBK");
            return ((bytes[0] & 255) << 8) + (bytes[1] & 255);
        } else {
            return unicodeCode;
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "·";
//        evaluate(s, 30, "ANC", "M", "未知");
        System.out.println(ByteCheckStringUDF.testCheck(s));
        System.out.println(ByteCheckStringUDF.isValid('一'));
    }
}
